package com.kaibes.module.monitior;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
import java.util.Properties;

import org.springframework.stereotype.Service;

import com.kaibes.core.base.util.LocalDateTimeUtils;
import com.kaibes.core.base.util.ObjectUtils;
import com.kaibes.module.monitior.pojo.AppDO;
import com.kaibes.module.monitior.pojo.CpuDO;
import com.kaibes.module.monitior.pojo.DiskDO;
import com.kaibes.module.monitior.pojo.JvmDO;
import com.kaibes.module.monitior.pojo.MemoryDO;
import com.kaibes.module.monitior.pojo.SystemDO;
import com.kaibes.web.util.IpUtils;

@Service
public class MonitorService {

    private final static DateTimeFormatter LOCAL_DATE_TIME = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter(Locale.CHINA);
    
    public AppDO getAppDO() {
        AppDO appDO = new AppDO();
        appDO.setName("KAIBES 软件系统");
        appDO.setVersion("1.0.0");
        
        Properties props = System.getProperties();
        appDO.setPath(props.getProperty("user.dir"));
        
        return appDO;
    }

    public CpuDO getCpuDO() {
        CpuDO cpuDO = new CpuDO();
        OperatingSystemMXBean system = ManagementFactory.getOperatingSystemMXBean();
        cpuDO.setCount(system.getAvailableProcessors());
//        System.out.println("系统名称:"+system.getName());
//        System.out.println("系统版本:"+system.getVersion());
//        System.out.println("操作系统的架构:"+system.getArch());
//        System.out.println("可用的内核数:"+system.getAvailableProcessors());
        
//        Double value = getValue(TAG_PROCESS_CPU_USAGE);
//        cpuDO.setProcessUsage(BigDecimalBuilder.newBuilder(value).multiply(HUNDRED).setScale(2).buildDouble());
//        
//        value = getValue(TAG_SYSTEM_CPU_USAGE);
//        cpuDO.setSystemUsage(BigDecimalBuilder.newBuilder(value).multiply(HUNDRED).setScale(2).buildDouble());
//        
//        cpuDO.setFreeUsage(BigDecimalBuilder.newBuilder(HUNDRED).subtract(cpuDO.getSystemUsage())
//                .subtract(cpuDO.getProcessUsage()).setScale(2).buildDouble());
        
        return cpuDO;
    }
    
    public MemoryDO getMemoryDO() {
        MemoryDO memoryDO = new MemoryDO();
        OperatingSystemMXBean system = ManagementFactory.getOperatingSystemMXBean();
        Long total = (Long) ObjectUtils.doMethod(system, "getTotalPhysicalMemorySize");
        memoryDO.setTotal(total);
        return memoryDO;
    }
    
    public JvmDO getJvmDO() {
        JvmDO jvmDO = new JvmDO();
        Runtime runtime = Runtime.getRuntime();
        jvmDO.setTotal(runtime.totalMemory());
        jvmDO.setMax(runtime.maxMemory());
        jvmDO.setFree(runtime.freeMemory());
        jvmDO.setUsed(jvmDO.getTotal()-jvmDO.getFree());
        
        Properties props = System.getProperties();
        jvmDO.setHome(props.getProperty("java.home"));
        
        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        jvmDO.setVersion(runtimeMXBean.getVmVersion());
        jvmDO.setJavaStandard(runtimeMXBean.getSpecVersion());
        jvmDO.setJavaVersion(props.getProperty("java.version"));
        
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        LocalDateTime localDateTime = LocalDateTimeUtils.fromMilliseconds(time);
        jvmDO.setStartTime(localDateTime.format(LOCAL_DATE_TIME));
        
        LocalDateTime start = LocalDateTimeUtils.fromMilliseconds(ManagementFactory.getRuntimeMXBean().getStartTime());
        LocalDateTime end = LocalDateTime.now();
        Duration duration = Duration.between(start, end);
        jvmDO.setRunDuration(duration.toDays() + "天" + duration.toHours()%24 + "小时" + duration.toMinutes()%60 + "分钟");
        
        jvmDO.setName(ManagementFactory.getRuntimeMXBean().getVmName());
        
        return jvmDO;
    }
    
    public SystemDO getSystemDO() {
        SystemDO systemDO = new SystemDO();
        Properties props = System.getProperties();
        systemDO.setComputerName(IpUtils.getHostName());
        systemDO.setComputerIp(IpUtils.getHostIp());
        systemDO.setOsName(props.getProperty("os.name"));
        systemDO.setOsArch(props.getProperty("os.arch"));
        systemDO.setUserDir(props.getProperty("user.dir"));
        return systemDO;
    }
    
    public DiskDO getDiskDO() {
        DiskDO diskDO = new DiskDO();
        Properties props = System.getProperties();
        File file = new File(props.getProperty("user.dir"));
        File parent = file.getParentFile();
        while (parent != null) {
            file = parent;
            parent = file.getParentFile();
        }
        diskDO.setName(file.getAbsolutePath());
        diskDO.setTotal(file.getTotalSpace());
        diskDO.setFree(file.getFreeSpace());
        diskDO.setUsed(diskDO.getTotal()-diskDO.getFree());
        return diskDO;
    }
    
//    public static String getMemery(){
//        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
//        // 总的物理内存+虚拟内存
//        long totalvirtualMemory = osmxb.getTotalSwapSpaceSize();
//        // 剩余的物理内存
//        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize();
//        Double compare=(Double)(1-freePhysicalMemorySize*1.0/totalvirtualMemory)*100;
//        String str="内存已使用:"+compare.intValue()+"%";
//        return str;
//      }
    
//    private Double getValue(String tag) {
//        Double value = metricsEndpoint.metric(tag, null).getMeasurements().get(0).getValue();
//        if (value < 0) {
//            return Double.valueOf("0.00");
//        } else {
//            return value;
//        }
//    }

}
